from functools import reduce
# CLASS 
class Pipe:
    def __init__(self):
        self.filters = []
    
    def add_filter(self, filter):
        self.filters.append(filter)
    
    def process(self, data):
        return reduce(lambda result, filter: filter.apply(result), self.filters, data)



class Filter:
    def __init__(self, transform):
        self.transform = transform
    
    def apply(self, data):
        return self.transform(data)


def print_return(aditional_text,data):
    print(f"{aditional_text} {data}")
    return data



# IMPLEMENTATION 
def exampleNormal():
    input_pipe = Pipe()

    filter_to_upper_case = Filter(lambda data: data.upper())
    print_filter_to_upper_case = Filter(lambda data: print_return('UPPER CASE :',data))

    filter_split = Filter(lambda data: data.split(' '))
    print_filter_split = Filter(lambda data: print_return('SPLIT :',data))

    input_pipe.add_filter(filter_to_upper_case)
    input_pipe.add_filter(print_filter_to_upper_case)
    input_pipe.add_filter(filter_split)
    input_pipe.add_filter(print_filter_split)


    pipe2 = Pipe()

    filter_contains_only = Filter(lambda data: list(filter(lambda word: 'PIPES' in word or 'FILTER' in word, data)))
    filter_counter = Filter(lambda data: len(data))
    print_filter_contains_only = Filter(lambda data: print_return('REMOVE NOT CONTAINING :',data))
    print_filter_counter = Filter(lambda data: print_return('COUNT :',data))


    pipe2.add_filter(filter_contains_only)
    pipe2.add_filter(print_filter_contains_only)
    pipe2.add_filter(filter_counter)
    pipe2.add_filter(print_filter_counter)

    data = input("Enter input: ")

    result1 = input_pipe.process(data)
    result2 = pipe2.process(result1)

    
def exampleCicle():
    pipe0 = Pipe()

    filter_convert_to_number = Filter(lambda data: int(data))
    filter_set_to_default = Filter(lambda data: data if data >= 1 else 0)

    pipe0.add_filter(filter_convert_to_number)
    pipe0.add_filter(filter_set_to_default)


    pipe1 = Pipe()

    def filter_fibonacci(n):
        if n <= 1:
            return n
        else:
            return pipe1.process(n - 1) + pipe1.process(n - 2)

    filter_fibonacci = Filter(filter_fibonacci)
    print_fibonaci_filter = Filter(lambda data: print_return(f'fibonaci rekursive resoult = ',data))
    pipe1.add_filter(filter_fibonacci)
    pipe1.add_filter(print_fibonaci_filter)



    

    data = int(input("Enter N for fibonaci: "))
    result0 = pipe0.process(data)

    result1 = pipe1.process(data)
    print(result1)

if __name__ == '__main__':
    while True:
        if int(input("select example: 1-normal | 2-cicle :  ")) == 1:
            exampleNormal()
        else:
            exampleCicle()
